﻿using Elsa.ActivityResults;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Services;
using Elsa.Services.Models;
using SqlSugar;
using Zhp.Common.Extention;
using Zhp.SqlSugar.UnitOfWork;
using Zhp.Workflow.Activities.DataOptions;
using Zhp.Workflow.Entity;
using Zhp.Workflow.Models;
using Zhp.Workflow.Notify;

namespace Zhp.Workflow.Activities
{
    [Trigger(Category = "工作流", DisplayName = "审批", Description = "审批流程", Outcomes = new[] { "同意", "拒绝" } )]
    public class ApproveActivity : Activity
    {
        private readonly ISqlSugarClient _dbContext;
        private readonly IApproverDataProvider _approverDataProvider;
        public ApproveActivity(IUnitOfWork<SugarUnitOfWork> unitOfWork, IApproverDataProvider approverDataProvider)
        {
            _dbContext = unitOfWork.Db;
            _approverDataProvider = approverDataProvider;
        }

        [ActivityInput(IsBrowsable = false, DefaultSyntax = SyntaxNames.Json, Label = "所有可以审批的人")]
        public List<string> ApproveUsersFullText { get; set; }

        [ActivityInput(
            UIHint = ActivityInputUIHints.MultiText,
            DefaultSyntax = SyntaxNames.Json,
            SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.Liquid, SyntaxNames.JavaScript },
            IsDesignerCritical = true,
            OptionsProvider = typeof(ApproveOptionsProvider),
            Label = "审批人")]
        public ICollection<string> ApproveUsers { get; set; }


        [ActivityInput(
            UIHint = ActivityInputUIHints.MultiText,
            DefaultSyntax = SyntaxNames.Json,
            SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.Liquid, SyntaxNames.JavaScript },
            IsDesignerCritical = true,
            OptionsProvider = typeof(ApproveOptionsProvider),
            Label = "审批角色")]
        public ICollection<string> ApproveRoles { get; set; }

        [ActivityInput(Label = "是否发送通知", SupportedSyntaxes = new[] { SyntaxNames.Literal, SyntaxNames.JavaScript, SyntaxNames.Liquid })]
        public bool IsSendNotify { get; set; }

        [ActivityInput(IsBrowsable = false, Label = "备注")]
        public string Remark { get; set; }

        [ActivityInput(IsBrowsable = false, Label = "审批人")]
        public string ApprovedBy { get; set; }

        [ActivityInput(UIHint = ActivityInputUIHints.SingleLine, Label = "标签(不同审批人看到的表单不同时使用)")]
        public string Tag { get; set; }

        protected override async ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context)
        {
            ApproveUsersFullText = new List<string>();
            var submitter = context.WorkflowInstance.Variables.Get(WorkflowVariables.SubmiterName)?.ToString();
            if (ApproveUsers?.Count > 0)
            {
                var allUsers = await _approverDataProvider.GetApproverUsers();
                var users = allUsers.Where(x => ApproveUsers.Contains(x.Value));
                ApproveUsersFullText.AddRange(users.Select(x => $"{x.Text}({x.Name})").ToList());
            }
            if (ApproveRoles?.Count > 0)
            {
                var allRoles = await _approverDataProvider.GetApproverRoles();
                var roles = allRoles.Where(x => ApproveRoles.Contains(x.Value));
                ApproveUsersFullText.AddRange(roles.Select(x => x.Text).ToList());
            }

            return Suspend();
        }

        /// <summary>
        /// 审批时进入这个方法继续执行流程
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected override async ValueTask<IActivityExecutionResult> OnResumeAsync(ActivityExecutionContext context)
        {
            ApproveInput input = context.Input as ApproveInput;
            Remark = input?.Remark;
            ApprovedBy = $"{input?.NickName}({input?.UserName})";
            var submitter = context.WorkflowInstance.Variables.Get(WorkflowVariables.SubmiterName)?.ToString();
            if (input?.Action == ApproveActionEnum.Agree || input?.Action == ApproveActionEnum.Refuse)
            {
                //记录已审批,做统计可能用到
                await _dbContext.Insertable(new WorkflowApproverRecord
                {
                    ActivityId = context.ActivityId,
                    WorkflowId = context.WorkflowInstance.Id,
                    UserId = input.UserId,
                    UserName = input.UserName,
                    NickName = input.NickName,
                    Tag = this.Tag,
                    WorkflowName = context.WorkflowExecutionContext.WorkflowBlueprint.Name,
                    ModelID = context.ContextId,
                    ModelType = context.WorkflowExecutionContext.WorkflowContext?.GetType()?.FullName,
                    Submitter = submitter,
                    ApproveTime = DateTime.Now,
                    Action = input.Action,
                    Remark = Remark
                }).ExecuteCommandAsync();

                return Outcome(input?.Action.GetDescription());
            }
            else
            {
                return Suspend();
            }
        }
    }

}
